<?php
function parseService($list = [])
{
    $upper = [];
    $lower = [];
    foreach($list as $item){
        $upper[] = strtoupper($item);
        $lower[] = strtolower($item);
    }
    return [
        'upper' => implode('_', $upper),
        'lower' => implode('.', $lower),
        'service' => implode('\\', $list)
    ];
}

function parseUrl($url)
{
    $url = trim($url, '/');
    $list = explode('/', $url);
    return $list;
}

function getContainer()
{
    return $GLOBALS['container'];
}

function selectFile($file)
{
    $configPath = CONFIG_PATH;
    $env = ENV;
    $file1 = "{$configPath}/{$env}/{$file}";
    $file2 = "{$configPath}/common/{$file}";
    if(file_exists($file1)){
        return $file1;
    }
    else{
        return $file2;
    }
}

function getConfig($file, $key = '')
{
    $data = yaml_parse_file(selectFile("{$file}.yaml"));
    if($key == ''){
        return $data;
    }
    else{
        return $data[$key];
    }
}

function getLanguage()
{
    $file = 'language.' . ADMIN_LANGUAGE;
    return getConfig($file);
}

function getMessage($key = '')
{
    $data = getConfig('message', THE_DEFAULT);
    $all = $data;
    if(isset($data['IMPORT'])){
        foreach($data['IMPORT'] as $file){
            $dataTemp = getConfig($file, THE_DEFAULT);
            $all = array_merge($all, $dataTemp);
        }
        unset($all['IMPORT']);
    }
    if($key == ''){
        return $all;
    }
    else{
        return $all[$key];
    }
}

function makeSuccess($data = [])
{
    $container = getContainer();
    $message = $container->getInstance('message');
    $message = $message['SUCCESS'];
    $result = [
        'code' => $message[0],
        'msg' => $message[1],
        'data' => $data
    ];
    if(count($data) == 2 && isset($data['list']) && isset($data['count'])){
        $result['count'] = $data['count'];
        $result['data'] = $data['list'];
    }
    $result = json_encode_plus($result);
    return $result;
}

function makeFail($key = 'FAIL', $diy = '', $line = 0)
{
    $container = getContainer();
    $message = $container->getInstance('message');
    $message = $message[$key];
    $result = [
        'code' => $message[0],
        'msg' => $message[1],
        'line' => $line
    ];
    if($diy != ''){
        $result['msg'] = $diy;
    }
    $result = json_encode_plus($result);
    return $result;
}

function hasFail($result)
{
    if(!is_string($result)){
        return false;
    }
    $result = json_decode($result, true);
    if($result['code'] != 0){
        return true;
    }
    return false;
}

function addDateTime($data, $flag)
{
    $dateTime = getDateTime();
    if($flag == THE_DATE){
        $data['dry_add_date'] = $dateTime['date'];
    }
    else if($flag == THE_TIME){
        $data['dry_add_time'] = $dateTime['date_time'];
    }
    else if($flag == THE_DATE_TIME){
        $data['dry_add_date'] = $dateTime['date'];
        $data['dry_add_time'] = $dateTime['date_time'];
    }
    return $data;
}

function getCategoryUpdateSortSql($config = [])
{
    $table = isset($config['table']) ? $config['table'] : 'dry_menu';
    $parentField = isset($config['parentField']) ? $config['parentField'] : 'dry_parent';
    $gradeField = isset($config['gradeField']) ? $config['gradeField'] : 'dry_grade';
    $sortField = isset($config['sortField']) ? $config['sortField'] : 'dry_sort';
    $dataSortField = isset($config['dataSortField']) ? $config['dataSortField'] : 'dry_data_sort';
    $sql = array();
    $sql[] = "
        update {$table} m
        set m.{$dataSortField}=concat(m.{$gradeField}+1000,m.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000)
        where m.{$gradeField}=1
        ";
    $sql[] = "
        update {$table} m
        left join {$table} p on p.id=m.{$parentField}
        set m.{$dataSortField}=concat(p.{$gradeField}+1000,p.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000)
        where m.{$gradeField}=2
        ";
    $sql[] = "
        update {$table} m
        left join {$table} p on p.id=m.{$parentField}
        left join {$table} pp on pp.id=p.{$parentField}
        set m.{$dataSortField}=concat(pp.{$gradeField}+1000,pp.{$sortField}+1000,p.{$gradeField}+1000,p.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000)
        where m.{$gradeField}=3
        ";
    $sql[] = "
        update {$table} m
        left join {$table} p on p.id=m.{$parentField}
        left join {$table} pp on pp.id=p.{$parentField}
        left join {$table} ppp on ppp.id=pp.{$parentField}
        set m.{$dataSortField}=concat(ppp.{$gradeField}+1000,ppp.{$sortField}+1000,pp.{$gradeField}+1000,pp.{$sortField}+1000,p.{$gradeField}+1000,p.{$sortField}+1000,m.{$gradeField}+1000,m.{$sortField}+1000)
        where m.{$gradeField}=4
        ";
    return $sql;
}

function makeRandOssObjectName()
{
    return date('Y/m/d/His-') . mt_rand(100000, 999999);
}

function getOssDomain()
{
    $config = getConfig('oss', THE_DEFAULT);
    return $config['domain'];
}

function getDomain()
{
    $config = getConfig(THE_DEFAULT, THE_DEFAULT);
    return $config['domain'];
}

function tryCall($instance, $alias, $action, $data, $serviceAutomate)
{
    $method = "{$alias}{$action}";
    if(method_exists($instance, $method)){
        return $instance->{$method}($alias, $data, $serviceAutomate);
    }
    return $data;
}

function getClassAndMethodFromCode($code = '')
{
    $list = token_get_all($code);
    $count = count($list);
    $data = [];
    $class = '';
    $method = [];
    foreach($list as $k => $v){
        if(is_array($v)){
            $v['name'] = token_name($v[0]);
            $v['content'] = $v[1];
            $v['line'] = $v[2];
            if(in_array($v['name'], ['T_CLASS', 'T_FUNCTION'])){
                $data[] = ['name' => $v['name'], 'index' => $k];
            }
        }
        $list[$k] = $v;
    }
    foreach($data as $v){
        for($i = $v['index'];$i < $count;$i++){
            $item = $list[$i];
            if(is_array($item) && $item['name'] == 'T_STRING'){
                if($v['name'] == 'T_CLASS'){
                    $class = $item['content'];
                }
                else if($v['name'] == 'T_FUNCTION'){
                    $method[] = $item['content'];
                }
                break;
            }
        }
    }
    return ['class' => $class, 'method' => $method];
}

function parseMethod($list = [])
{
    $data = [
        'all' => [],
        'common' => [],
        'extension' => []
    ];
    foreach($list as $item){
        if(endWith($item, 'Action')){
            $name = rtrimPlus($item, 'Action');
            if(in_array($name, ['index', 'show', 'new', 'edit', 'delete'])){
                $data['common'][] = $name;
            }
            else{
                $data['extension'][] = $name;
            }
            $data['all'][] = $name;
        }
    }
    return $data;
}

function csrfEncrypt($data = '', $time = HOUR_SECOND)
{
    $temp = [
        'data' => $data,
        'expire' => getTimestamp() + $time
    ];
    return getContainer()->get(CORE_ENCRYPT)->setKey('csrf')->encrypt(json_encode($temp));
}

function csrfDecrypt($data = '')
{
    $temp = getContainer()->get(CORE_ENCRYPT)->setKey('csrf')->decrypt($data);
    if(!$temp){
        return false;
    }
    $temp = json_decode($temp, true);
    if(getTimestamp() <= $temp['expire']){
        return $temp['data'];
    }
    return false;
}

function checkValidCode($code1, $code2)
{
    return strtolower($code1) == strtolower($code2);
}

function isMessageCode($code)
{
    if(!is_numeric($code)){
        return false;
    }
    if($code >= 100000 && $code <= 999999){
        return true;
    }
    else{
        return false;
    }
}

function makeMessageCode()
{
    return mt_rand(100000, 999999);
}

function addPageInformation($data, $page, $limit, $count)
{
    $data['page'] = $page;
    $data['limit'] = $limit;
    $data['count'] = $count;
    $data['total_page'] = getTotalPage($count, $limit);
    if($data['total_page'] > $page){
        $data['next'] = 1;
    }
    else{
        $data['next'] = 0;
    }
    return $data;
}

function css($v)
{
    $r = '?v=' . CSS_JS_VERSION;
    return "<link rel='stylesheet' media='all' href='{$v['path']}{$r}'>";
}

function js($v)
{
    $r = '?v=' . CSS_JS_VERSION;
    return "<script src='{$v['path']}{$r}' {$v['flag']}></script>";
}

function makeCharacter($start, $end)
{
    $list = [];
    $i = $start;
    for($i >= $start;$i <= $end;$i++){
        $list[] = chr($i);
    }
    return $list;
}

function checkPassword($password)
{
    $length = strlen($password);
    if($length < 9 || $length > 16){
        return false;
    }
    $type1 = 0;
    $type2 = 0;
    $type3 = 0;
    $set1 = [
        '!',
        '"',
        '#',
        '$',
        '%',
        '&',
        "'",
        '(',
        ')',
        '*',
        '+',
        ',',
        '-',
        '.',
        '/',
        ':',
        ';',
        '<',
        '=',
        '>',
        '?',
        '@',
        '[',
        '\\',
        ']',
        '^',
        '_',
        '`',
        '{',
        '|',
        '}',
        '~'
    ];
    $set2 = makeCharacter(48, 57);
    $temp1 = makeCharacter(65, 90);
    $temp2 = makeCharacter(97, 122);
    $set3 = array_merge($temp1, $temp2);
    $i = 0;
    for($i >= 0;$i <= $length - 1;$i++){
        $current = $password[$i];
        if(in_array($current, $set1)){
            $type1 = 1;
        }
        if(in_array($current, $set2)){
            $type2 = 1;
        }
        if(in_array($current, $set3)){
            $type3 = 1;
        }
    }
    if($type1 + $type2 + $type3 >= 2){
        return true;
    }
    else{
        return false;
    }
}

function isNodeNameTaskDaemon()
{
    if(isset($_SERVER['DRY_NODE_NAME']) && contain($_SERVER['DRY_NODE_NAME'], 'task_daemon')){
        return true;
    }
    return false;
}